# -*- coding: utf-8 -*-
"""
LASSO
Created on Mon Apr 16 19:54:38 2018

@author: Allen
"""
import numpy as np
import matplotlib.pyplot as plt

np.random.seed( 42 )

x = np.random.uniform( -3.0, 3.0, size = 100 )
X = x.reshape( -1, 1 )
y = 0.5 * x + 3 + np.random.normal( 0, 1, size = 100 )

plt.scatter( x, y )
plt.show()

from sklearn.model_selection import train_test_split
np.random.seed( 666 )
X_train, X_test, y_train, y_test = train_test_split( X, y )

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import PolynomialFeatures
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression

def PolynomialRegression( degree ):
    return Pipeline([
                ( "poly", PolynomialFeatures( degree = degree ) ),
                ( "std_scaler", StandardScaler() ),
                ( "lin_reg", LinearRegression() )
            ])

from sklearn.metrics import mean_squared_error

poly10_reg = PolynomialRegression( degree = 20 )
poly10_reg.fit( X_train, y_train )

y10_predict = poly10_reg.predict( X_test )
print( mean_squared_error( y_test, y10_predict ) ) # 167.940108614


def plot_model( model ):
    x_plot = np.linspace( -3, 3, 100 ).reshape( 100, 1 )
    y_plot = model.predict( x_plot )
    
    plt.scatter( x, y )
    plt.plot( x_plot[:,0], y_plot, color = "r" )
    plt.axis( [ -3, 3, 0, 6 ] )
    plt.show()
    
plot_model( poly10_reg )

from sklearn.linear_model import Lasso

def LassoRegression( degree, alpha ):
    return Pipeline([
                ( "poly", PolynomialFeatures( degree = degree ) ),
                ( "std_scaler", StandardScaler() ),
                ( "lin_reg", Lasso( alpha = alpha ) )
            ])

lasso1_reg = LassoRegression( 20, 0.01 )
lasso1_reg.fit( X_train, y_train )
y1_predict = lasso1_reg.predict( X_test )
print( mean_squared_error( y_test, y1_predict ) ) # 1.14960808433
plot_model( lasso1_reg )

lasso2_reg = LassoRegression( 20, 0.1 )
lasso2_reg.fit( X_train, y_train )
y2_predict = lasso2_reg.predict( X_test )
print( mean_squared_error( y_test, y2_predict ) ) # 1.12139113518
plot_model( lasso2_reg )

lasso3_reg = LassoRegression( 20, 1 )
lasso3_reg.fit( X_train, y_train )
y3_predict = lasso3_reg.predict( X_test )
print( mean_squared_error( y_test, y3_predict ) ) # 1.84089396595
plot_model( lasso3_reg )

'''
岭回归，在alpha逐步增大的时候，曲线逐渐便缓，但始终是一条曲线。
使用lasso，曲线更倾向于一条曲线
从准确的角度来讲，还是岭回归更为准确，但是特征很大的情况下，使用lasso可以将特征变小
注意： 优先使用岭回归；当特征数量非常多的话，优先选择弹性网（elastic net）

'''


